package com.vtquang.magic.controls;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;

import com.vtquang.magic.PitchAzimuthCalculator;
import com.vtquang.magic.global.GlobalInfo;
import com.vtquang.magic.paintable.PaintableCircle;
import com.vtquang.magic.paintable.PaintableLine;
import com.vtquang.magic.paintable.PaintablePosition;
import com.vtquang.magic.paintable.PaintableRadarPoints;
import com.vtquang.magic.paintable.PaintableText;
import com.vtquang.magic.utils.ScreenPositionUtility;

public class Radar {
	public static final float RADIUS = 52;

	private static final int LINE_COLOR = Color.argb(150, 0, 0, 220);
	private static final float PAD_X = 10;
	private static final float PAD_Y = 25;
	private static final int RADAR_COLOR = Color.argb(100, 0, 0, 200);
	private static final int TEXT_COLOR = Color.rgb(255, 255, 255);
	private static final int TEXT_SIZE = 12;

	private static ScreenPositionUtility leftRadarLine = null;
	private static ScreenPositionUtility rightRadarLine = null;
	private static PaintablePosition leftLineContainer = null;
	private static PaintablePosition rightLineContainer = null;
	private static PaintablePosition circleContainer = null;

	private static PaintableRadarPoints radarPoints = null;
	private static PaintablePosition pointsContainer = null;

	private static PaintableText paintableText = null;
	private static PaintablePosition paintedContainer = null;

	private PaintablePosition circleContainer1;

	private PaintablePosition circleContainer2;

	private PaintablePosition circleContainer3;

	private PaintablePosition circleContainer4;

	private PaintablePosition XContainer;

	private PaintablePosition YContainer;

	private Paint paintArc;

	public Radar() {
		if (leftRadarLine == null)
			leftRadarLine = new ScreenPositionUtility();
		if (rightRadarLine == null)
			rightRadarLine = new ScreenPositionUtility();
	}

	public void draw(Canvas canvas) {
		if (canvas == null)
			throw new NullPointerException();

		PitchAzimuthCalculator.calcPitchBearing(GlobalInfo.getRotationMatrix());
		GlobalInfo.setAzimuth(PitchAzimuthCalculator.getAzimuth());
		GlobalInfo.setPitch(PitchAzimuthCalculator.getPitch());

		drawRadarCircle(canvas);
		drawRadarPoints(canvas);
		drawRadarLines(canvas);
		drawRadarText(canvas);
	}

	private void drawRadarCircle(Canvas canvas) {
		if (canvas == null)
			throw new NullPointerException();

		if (circleContainer == null) {
			PaintableCircle paintableCircle = new PaintableCircle(Color.GREEN,
					RADIUS, false);
			paintableCircle.setStrokeWidth(3);
			circleContainer = new PaintablePosition(paintableCircle, PAD_X
					+ RADIUS, PAD_Y + RADIUS, 0, 1);

			PaintableCircle paintableCircle1 = new PaintableCircle(Color.GREEN,
					RADIUS - 10, false);
			paintableCircle1.setStrokeWidth(0.5f);
			circleContainer1 = new PaintablePosition(paintableCircle1, PAD_X
					+ RADIUS, PAD_Y + RADIUS, 0, 1);

			PaintableCircle paintableCircle2 = new PaintableCircle(Color.GREEN,
					RADIUS - 20, false);
			paintableCircle2.setStrokeWidth(0.5f);
			circleContainer2 = new PaintablePosition(paintableCircle2, PAD_X
					+ RADIUS, PAD_Y + RADIUS, 0, 1);

			PaintableCircle paintableCircle4 = new PaintableCircle(Color.GREEN,
					RADIUS - 30, false);
			paintableCircle4.setStrokeWidth(0.5f);
			circleContainer4 = new PaintablePosition(paintableCircle4, PAD_X
					+ RADIUS, PAD_Y + RADIUS, 0, 1);

			PaintableCircle paintableCircle3 = new PaintableCircle(Color.GREEN,
					RADIUS, true);
			paintableCircle3.setShader(new SweepGradient(PAD_X + RADIUS, PAD_Y
					+ RADIUS, Color.GREEN, Color.TRANSPARENT));
			circleContainer3 = new PaintablePosition(paintableCircle3, PAD_X
					+ RADIUS, PAD_Y + RADIUS, 0, 1);
		}
		circleContainer3.paint(canvas);
		circleContainer.paint(canvas);
		circleContainer1.paint(canvas);
		circleContainer2.paint(canvas);
		circleContainer4.paint(canvas);
	}

	private void drawRadarPoints(Canvas canvas) {
		if (canvas == null)
			throw new NullPointerException();

		if (radarPoints == null)
			radarPoints = new PaintableRadarPoints();

		if (pointsContainer == null)
			pointsContainer = new PaintablePosition(radarPoints, PAD_X, PAD_Y,
					-GlobalInfo.getAzimuth(), 1);
		else
			pointsContainer.set(radarPoints, PAD_X, PAD_Y,
					-GlobalInfo.getAzimuth(), 1);

		pointsContainer.paint(canvas);
	}

	private void drawRadarLines(Canvas canvas) {
		if (canvas == null)
			throw new NullPointerException();

//		if (leftLineContainer == null) {
//			leftRadarLine.set(0, -RADIUS);
//			leftRadarLine.rotate(-CameraModel.DEFAULT_VIEW_ANGLE / 2);
//			leftRadarLine.add(PAD_X + RADIUS, PAD_Y + RADIUS);
//
//			float leftX = leftRadarLine.getX() - (PAD_X + RADIUS);
//			float leftY = leftRadarLine.getY() - (PAD_Y + RADIUS);
//			PaintableLine leftLine = new PaintableLine(LINE_COLOR, leftX, leftY);
//			leftLineContainer = new PaintablePosition(leftLine, PAD_X + RADIUS,
//					PAD_Y + RADIUS, 0, 1);
//		}
//		leftLineContainer.paint(canvas);
//
//		if (rightLineContainer == null) {
//			rightRadarLine.set(0, -RADIUS);
//			rightRadarLine.rotate(CameraModel.DEFAULT_VIEW_ANGLE / 2);
//			rightRadarLine.add(PAD_X + RADIUS, PAD_Y + RADIUS);
//
//			float rightX = rightRadarLine.getX() - (PAD_X + RADIUS);
//			float rightY = rightRadarLine.getY() - (PAD_Y + RADIUS);
//			PaintableLine rightLine = new PaintableLine(LINE_COLOR, rightX,
//					rightY);
//			rightLineContainer = new PaintablePosition(rightLine, PAD_X
//					+ RADIUS, PAD_Y + RADIUS, 0, 1);
//		}
//		rightLineContainer.paint(canvas);
		
		if(paintArc == null){
			paintArc = new Paint();
			paintArc.setStyle(Paint.Style.FILL); 
			Shader gradient = new SweepGradient (PAD_X + RADIUS, PAD_Y + RADIUS, Color.TRANSPARENT, Color.parseColor("#8000FF00"));
			paintArc.setShader(gradient);
		}
		canvas.drawArc(new RectF(PAD_X, PAD_Y, PAD_X + 2 * RADIUS, PAD_Y + 2 * RADIUS), (45 / 2.0f) - 90, -45, true, paintArc);

		if (XContainer == null) {
			PaintableLine XLine = new PaintableLine(Color.GREEN, 0, 2 * RADIUS);
			XLine.setStrokeWidth(0.5f);
			XContainer = new PaintablePosition(XLine, PAD_X + RADIUS, PAD_Y, 0,
					1);
		}
		XContainer.paint(canvas);

		if (YContainer == null) {
			PaintableLine YLine = new PaintableLine(Color.GREEN, 2 * RADIUS, 0);
			YLine.setStrokeWidth(0.5f);
			YContainer = new PaintablePosition(YLine, PAD_X, PAD_Y + RADIUS, 0,
					1);
		}
		YContainer.paint(canvas);  
	}

	private void drawRadarText(Canvas canvas) {
		if (canvas == null)
			throw new NullPointerException();
//		int range = (int) (GlobalInfo.getAzimuth() / (360f / 16f));
//		String dirTxt = "";
//		if (range == 15 || range == 0)
//			dirTxt = "N";
//		else if (range == 1 || range == 2)
//			dirTxt = "NE";
//		else if (range == 3 || range == 4)
//			dirTxt = "E";
//		else if (range == 5 || range == 6)
//			dirTxt = "SE";
//		else if (range == 7 || range == 8)
//			dirTxt = "S";
//		else if (range == 9 || range == 10)
//			dirTxt = "SW";
//		else if (range == 11 || range == 12)
//			dirTxt = "W";
//		else if (range == 13 || range == 14)
//			dirTxt = "NW";
//		int bearing = (int) GlobalInfo.getAzimuth();
//		radarText(canvas, "" + bearing + ((char) 176) + " " + dirTxt,
//				(PAD_X + RADIUS), (PAD_Y - 5), true);
//
//		radarText(canvas, formatDist(GlobalInfo.getRadius() * 1000),
//				(PAD_X + RADIUS), (PAD_Y + RADIUS * 2 - 10), false);
		
		radarText(canvas, formatDist(GlobalInfo.getRadius() * 1000),
				(PAD_X + RADIUS), (PAD_Y - 7), true);
	}

	private void radarText(Canvas canvas, String txt, float x, float y,
			boolean bg) {
		if (canvas == null || txt == null)
			throw new NullPointerException();

		if (paintableText == null)
			paintableText = new PaintableText(txt, TEXT_COLOR, TEXT_SIZE, bg);
		else
			paintableText.set(txt, TEXT_COLOR, TEXT_SIZE, bg);

		if (paintedContainer == null)
			paintedContainer = new PaintablePosition(paintableText, x, y, 0, 1);
		else
			paintedContainer.set(paintableText, x, y, 0, 1);

		paintedContainer.paint(canvas);
	}

	private static String formatDist(float meters) {
		if (meters < 1000) {
			return ((int) meters) + "m";
		} else if (meters < 10000) {
			return formatDec(meters / 1000f, 1) + "km";
		} else {
			return ((int) (meters / 1000f)) + "km";
		}
	}

	private static String formatDec(float val, int dec) {
		int factor = (int) Math.pow(10, dec);

		int front = (int) (val);
		int back = (int) Math.abs(val * (factor)) % factor;

		return front + "." + back;
	}
}